
var path = require('path');
var mongoose = require('mongoose');
var jwt = require('jwt-simple');
var moment = require('moment');
mongoose.Promise = global.Promise; //plugging in your own Promises Library

const RESPONSE = {
    message: "",
    data: "",
    status: false,
}

module.exports = function (app) {
    const db = connectToMongoDB();
    const modelObj = defineModels();
    // app.set('jwtTokenSecret', 'YOUR_SECRET_STRING');
    app.post('/login', (req, res) => {
        login(modelObj.user_Model, req, res);
    });

    app.post('/register', (req, res) => {
        register(modelObj.user_Model, req, res);
    })

    app.use(auth);

    app.post('/app/addArticle', (req, res) => {
        addArticle(modelObj.article_Model, req, res);
    });

    app.post('/app/updateArticle', (req, res) => {
        updateArticle(modelObj.article_Model, req, res);
    });

    app.get('/app/deleteArticle', (req, res) => {
        deleteArticle(modelObj.article_Model, req, res);
    });

    app.get('/app/getArticle', (req, res) => {
        getArticle(modelObj.article_Model, req, res);
    });

    app.get('/app/getAppData', (req, res) => {
        res.sendFile(path.join(__dirname, '../public/1.png'));
    });


    //define Models
    function defineModels() {
        //define Schema
        const schemaObj = {
            article: {
                collection: 'article',
                model: {
                    title: String,
                    link: String,
                    aLink: String,
                    content: String,
                    tag: String,
                }
            },
            user: {
                collection: 'users',
                model: {
                    username: String,
                    password: String,
                }
            }
        }
        //article model
        const article_Schema = mongoose.Schema(schemaObj.article.model);
        const article_Model = mongoose.model(schemaObj.article.collection, article_Schema);

        //user model
        const user_Schema = mongoose.Schema(schemaObj.user.model);
        const user_Model = mongoose.model(schemaObj.user.collection, user_Schema);
        // console.log('showcase_Model', showcase_Model);
        const modelObj = {
            article_Model,
            user_Model
        }
        return modelObj;
    }

    //connect to DB
    function connectToMongoDB() {
        mongoose.connect('mongodb://localhost/mic');
        var db = mongoose.connection;
        db.once('open', () => {
            console.log('good to go!');
        })
            .on('error', (error) => {
                console.warn('Warning', error);
            });
        return db;
    }


    function addArticle(model, req, res) {
        const data = req.body;
        const update = {
            title: data.title,
            link: data.link,
            aLink: data.aLink,
            content: data.content,
            tag: data.tag,
        }
        model.create(update)
            .then((data) => {
                const options = {
                    upsert: true
                };
                const updateLink = {
                    link: `/home/${data._id}`,
                    aLink: `/admin/${data._id}`
                }
                model.findByIdAndUpdate(data._id, updateLink, options)
                    .then((data) => {
                        if (data) {
                            RESPONSE.message = "Add article successfully!";
                            RESPONSE.status = true;
                            RESPONSE.data = data;
                            res.send({ message: RESPONSE.message, status: RESPONSE.status, data: RESPONSE.data });
                        } else {
                            RESPONSE.message = "Failed to Add!";
                            RESPONSE.status = false;
                            RESPONSE.data = data;
                            res.send({ message: RESPONSE.message, status: RESPONSE.status, data: RESPONSE.data });
                        }
                    });
            });
    }

    function updateArticle(model, req, res) {
        const data = req.body;
        const options = {
            upsert: true
        };
        const update = {
            title: data.title,
            link: data.link,
            aLink: data.aLink,
            content: data.content,
            tag: data.tag,
        }
        model.findByIdAndUpdate(data._id, update, options)
            .then((data) => {
                if (data) {
                    RESPONSE.message = "Update article successfully!";
                    RESPONSE.status = true;
                    RESPONSE.data = data;
                    res.send({ message: RESPONSE.message, status: RESPONSE.status, data: RESPONSE.data });
                } else {
                    RESPONSE.message = "Failed to Update!";
                    RESPONSE.status = false;
                    RESPONSE.data = data;
                    res.send({ message: RESPONSE.message, status: RESPONSE.status, data: RESPONSE.data });
                }
            });
    }

    function deleteArticle(model, req, res) {

        model.findOneAndRemove({ _id: req.query._id })
            .then((data) => {
                if (data) {
                    RESPONSE.message = "Delete article successfully!";
                    RESPONSE.status = true;
                    RESPONSE.data = data;
                    res.send({ message: RESPONSE.message, status: RESPONSE.status, data: RESPONSE.data });
                } else {
                    RESPONSE.message = "Failed to Delete!";
                    RESPONSE.status = false;
                    RESPONSE.data = data;
                    res.send({ message: RESPONSE.message, status: RESPONSE.status, data: RESPONSE.data });
                }

            });
    }

    function getArticle(model, req, res) {

        model.find({})
            .then((data) => {
                const articles = data.map((obj) => {
                    return {
                        _id: obj._id,
                        title: obj.title,
                        link: obj.link,
                        aLink: obj.aLink,
                        content: obj.content,
                        tag: obj.tag
                    }
                })
                RESPONSE.message = "Fetch articles successfully!";
                RESPONSE.status = true;
                RESPONSE.data = articles;
                res.send({ message: RESPONSE.message, status: RESPONSE.status, data: RESPONSE.data });
            });
    }

    function auth(req, res, next) {
        let expireTime = 1000 * 60;
        res.header('Access-Control-Expose-Headers', 'access-token');
        const now = Date.now();

        let unauthorized = true;
        const token = req.headers['access-token'];
        if (token) {
            const expired = now - token > expireTime;
            if (!expired) {
                unauthorized = false;
                res.header('access-token', now);
            }
        }
        console.log(req.path);
        if (unauthorized) {
            res.sendStatus(401);
        } else {
            next();
        }
    }

    function login(model, req, res) {
        res.header('Access-Control-Expose-Headers', 'access-token');
        const { username, password } = req.body;
        console.info('body', req.body);
        model.findOne({ username: username })
            .then((data) => {
                console.log(data);
                if (data && data.password === password) {
                    res.header('access-token', Date.now());
                    RESPONSE.message = "Login Successfully!";
                    RESPONSE.status = true;
                    RESPONSE.data = null;
                    res.send(RESPONSE);
                } else {
                    RESPONSE.message = "Username or Password is not correct!";
                    RESPONSE.status = false;
                    RESPONSE.data = null;
                    res.send(RESPONSE);
                }
            })
    }

    function register(model, req, res) {
        res.header('Access-Control-Expose-Headers', 'access-token');
        const options = {
            upsert: true
        };
        const { username, password } = req.body;
        const update = {
            username,
            password
        };
        model.findOne({ username: username })
            .then((data) => {
                console.log('data', data);
                if (!data) {
                    model.findOneAndUpdate({ username: username }, update, options)
                        .then((data) => {
                            res.header('access-token', Date.now());
                            RESPONSE.message = "Register Successfully!";
                            RESPONSE.status = true;
                            RESPONSE.data = null;
                            res.send({ message: RESPONSE.message, status: RESPONSE.status, data: RESPONSE.data });
                        });
                } else {
                    RESPONSE.message = "Register Falied!";
                    RESPONSE.status = false;
                    RESPONSE.data = null;
                    res.send({ message: RESPONSE.message, status: RESPONSE.status, data: RESPONSE.data });
                }
            })
    }

}